package com.coai.user.service

import com.coai.common.exception.ConflictException
import com.coai.common.exception.ResourceNotFoundException
import com.coai.user.model.*
import com.coai.user.repository.*
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * 权限服务
 */
@Service
class PermissionService(
    private val roleRepository: RoleRepository,
    private val permissionRepository: PermissionRepository,
    private val userRoleRepository: UserRoleRepository,
    private val rolePermissionRepository: RolePermissionRepository
) {
    
    /**
     * 创建角色
     */
    @Transactional
    fun createRole(
        name: String,
        code: String,
        type: RoleType = RoleType.CUSTOM,
        description: String? = null
    ): Role {
        
        if (roleRepository.existsByCode(code)) {
            throw ConflictException("角色代码已存在")
        }
        
        val role = Role(
            name = name,
            code = code,
            type = type,
            description = description
        )
        
        return roleRepository.save(role)
    }
    
    /**
     * 分配角色给用户
     */
    @Transactional
    fun assignRoleToUser(userId: String, roleId: String) {
        
        if (!roleRepository.existsById(roleId)) {
            throw ResourceNotFoundException("角色不存在")
        }
        
        if (userRoleRepository.existsByUserIdAndRoleId(userId, roleId)) {
            throw ConflictException("用户已拥有该角色")
        }
        
        val userRole = UserRole(
            userId = userId,
            roleId = roleId
        )
        
        userRoleRepository.save(userRole)
    }
    
    /**
     * 移除用户角色
     */
    @Transactional
    fun removeRoleFromUser(userId: String, roleId: String) {
        userRoleRepository.deleteByUserIdAndRoleId(userId, roleId)
    }
    
    /**
     * 创建权限
     */
    @Transactional
    fun createPermission(
        name: String,
        code: String,
        resource: String,
        action: String,
        description: String? = null
    ): Permission {
        
        if (permissionRepository.existsByCode(code)) {
            throw ConflictException("权限代码已存在")
        }
        
        val permission = Permission(
            name = name,
            code = code,
            resource = resource,
            action = action,
            description = description
        )
        
        return permissionRepository.save(permission)
    }
    
    /**
     * 分配权限给角色
     */
    @Transactional
    fun assignPermissionToRole(roleId: String, permissionId: String) {
        
        if (!roleRepository.existsById(roleId)) {
            throw ResourceNotFoundException("角色不存在")
        }
        
        if (!permissionRepository.existsById(permissionId)) {
            throw ResourceNotFoundException("权限不存在")
        }
        
        if (rolePermissionRepository.existsByRoleIdAndPermissionId(roleId, permissionId)) {
            throw ConflictException("角色已拥有该权限")
        }
        
        val rolePermission = RolePermission(
            roleId = roleId,
            permissionId = permissionId
        )
        
        rolePermissionRepository.save(rolePermission)
    }
    
    /**
     * 获取用户的所有权限
     */
    fun getUserPermissions(userId: String): List<Permission> {
        // 1. 获取用户的角色
        val roleIds = userRoleRepository.findRoleIdsByUserId(userId)
        
        if (roleIds.isEmpty()) {
            return emptyList()
        }
        
        // 2. 获取角色的权限
        val permissionIds = rolePermissionRepository.findPermissionIdsByRoleIds(roleIds)
        
        if (permissionIds.isEmpty()) {
            return emptyList()
        }
        
        // 3. 获取权限详情
        return permissionRepository.findAllById(permissionIds)
    }
    
    /**
     * 检查用户是否有权限
     */
    fun hasPermission(userId: String, resource: String, action: String): Boolean {
        val permissions = getUserPermissions(userId)
        return permissions.any { it.resource == resource && it.action == action }
    }
    
    /**
     * 获取用户的角色列表
     */
    fun getUserRoles(userId: String): List<Role> {
        val roleIds = userRoleRepository.findRoleIdsByUserId(userId)
        return roleRepository.findAllById(roleIds)
    }
    
    /**
     * 初始化系统权限
     */
    @Transactional
    fun initializeSystemPermissions() {
        val permissions = listOf(
            // 用户管理
            Triple("user:view", "user", "VIEW"),
            Triple("user:create", "user", "CREATE"),
            Triple("user:update", "user", "UPDATE"),
            Triple("user:delete", "user", "DELETE"),
            
            // 组织管理
            Triple("org:view", "organization", "VIEW"),
            Triple("org:create", "organization", "CREATE"),
            Triple("org:update", "organization", "UPDATE"),
            Triple("org:delete", "organization", "DELETE"),
            
            // 角色权限
            Triple("role:view", "role", "VIEW"),
            Triple("role:create", "role", "CREATE"),
            Triple("role:update", "role", "UPDATE"),
            Triple("role:delete", "role", "DELETE"),
            
            // 消息管理
            Triple("message:send", "message", "SEND"),
            Triple("message:view", "message", "VIEW"),
            Triple("message:delete", "message", "DELETE"),
            
            // 文件管理
            Triple("file:upload", "file", "UPLOAD"),
            Triple("file:download", "file", "DOWNLOAD"),
            Triple("file:delete", "file", "DELETE"),
            
            // 通话管理
            Triple("call:initiate", "call", "INITIATE"),
            Triple("call:join", "call", "JOIN"),
            Triple("call:end", "call", "END")
        )
        
        permissions.forEach { (code, resource, action) ->
            if (!permissionRepository.existsByCode(code)) {
                createPermission(
                    name = code.replace(":", " ").uppercase(),
                    code = code,
                    resource = resource,
                    action = action,
                    description = "系统权限：$code"
                )
            }
        }
    }
}
